<template>
  <div class="flex flex-col h-full">
    <div class="my-4 flex flex-row-reverse">
      <el-tooltip effect="light" content="点击获取最新数据" placement="bottom">
        <el-button
          class="ml-2 mr-2"
          v-if="tools.query"
          @click="getData"
          type="success"
          >查询</el-button
        >
      </el-tooltip>
      <el-button
        class="ml-2 mr-2"
        @click="handleSave"
        type="success"
        :disabled="EditDisabled"
        >保存</el-button
      >
      <el-tooltip effect="light" content="导出" placement="bottom">
        <el-button
          class="ml-2 mr-2"
          v-if="tools.export"
          @click="handleExport"
          type="primary"
          >导出</el-button
        >
      </el-tooltip>
      <el-tooltip effect="light" content="导入" placement="bottom">
        <el-button
          class="ml-2 mr-2"
          v-if="tools.import"
          @click="handleImport"
          type="primary"
          >导入</el-button
        >
      </el-tooltip>
    </div>
    <el-divider></el-divider>
    <div>
      <slot name="form"></slot>
    </div>
    <div class="flex-1" style="width: 100%; overflow-x: auto">
      <el-table
        :data="tableData"
        @row-click="editRow"
        :header-cell-style="
          () => {
            return {
              background: 'rgba(28, 155, 252, 0.02)',
              color: 'rgb(142, 155, 185)',
              textAlign: 'center',
            };
          }
        "
        style="width: 100%; height: 100%"
      >
        <el-table-column
          resizable
          align="center"
          :width="column.width || 140"
          v-for="(column, index) in columns"
          :key="index"
          :label="column.label"
          :prop="column.prop"
        >
          <template slot-scope="scope" v-if="!column.hidden">
            <span v-if="!scope.row.editable">
              <span v-if="column.type === 'checkBox'">
                <el-checkbox
                  v-if="column.type === 'checkBox'"
                  :true-label="1"
                  :false-label="0"
                  v-model="scope.row[column.prop]"
                  :name="column.prop"
                ></el-checkbox>
              </span>
              <span v-else-if="column.hidden">
                {{ scope.row[column.prop] }}
              </span>
              <span v-else-if="column.type === 'select'" class="truncate">
                {{ id2Text(column.options, scope.row[column.prop]) }}
              </span>
              <span v-else-if="column.type === 'multiCheck'" class="truncate">
                <span
                  @click="multiChexk(column.options, scope.row[column.prop])"
                >
                  {{ id2Text(column.options, scope.row[column.prop]) }}
                </span>
              </span>
              <span v-else class="truncate">
                {{ scope.row[column.prop] }}
              </span>
            </span>
            <span v-if="!scope.row.editable">
              <el-button
                size="mini"
                v-if="
                  !scope.row[column.prop] &&
                  column.type === 'operate' &&
                  !column.noDel &&
                  scope.row.id
                "
                type="danger"
                @click="doDel(scope.row[column.id])"
              >
                删除
              </el-button>
            </span>
            <template v-else>
              <template v-if="column.type === 'input'">
                <el-input
                  clearable
                  @blur="validate(scope.row, column)"
                  :disabled="column.disabled"
                  v-model="scope.row[column.prop]"
                ></el-input>
              </template>
              <template v-else-if="column.type === 'number'">
                <el-input-number
                  clearable
                  :disabled="column.disabled"
                  v-model="scope.row[column.prop]"
                ></el-input-number>
              </template>
              <template v-else-if="column.type === 'checkBox'">
                <el-checkbox
                  :disabled="column.disabled"
                  :true-label="1"
                  :false-label="0"
                  v-model="scope.row[column.prop]"
                  :name="column.prop + ''"
                ></el-checkbox>
              </template>
              <template v-else-if="column.type === 'select'">
                <el-select
                  clearable
                  @visible-change="clickOpt($event, scope.row, column)"
                  @focus="column.getOptions ? column.getOptions : () => {}"
                  v-model="scope.row[column.prop]"
                >
                  <el-option
                    v-for="option in column.options"
                    :key="option.value"
                    :label="option.label + ''"
                    :value="option.value"
                  ></el-option>
                </el-select>
              </template>
              <template v-else-if="column.type === 'multiCheck'">
                <span
                  @click="multiChexk(column.options, scope.row[column.prop])"
                >
                  {{
                    id2Text(column.options, scope.row[column.prop]) || "请选择"
                  }}</span
                >
                <!-- 弹窗 -->
                <el-dialog
                  title="提示"
                  :visible.sync="dialogVisible"
                  width="30%"
                >
                  <el-checkbox-group v-model="checkList" @change="change">
                    <el-checkbox
                      :label="option.label + ''"
                      :value="option.value"
                      v-for="option in column.options"
                      :key="option.value"
                    ></el-checkbox>
                  </el-checkbox-group>
                  <el-button slot="reference">click 激活</el-button>
                  <span slot="footer" class="dialog-footer">
                    <el-button @click="dialogVisible = false">取 消</el-button>
                    <el-button
                      type="primary"
                      @click="
                        confirmDialog(column.options, scope.row, column.prop)
                      "
                      >确 定</el-button
                    >
                  </span>
                </el-dialog>
              </template>
              <template v-if="scope.row.editable && !column.hidden"> </template>
            </template>
          </template>
        </el-table-column>
      </el-table>
    </div>
  </div>
</template>

<script>
import request from "@/utils/request";
export default {
  name: "dmbEditTable",
  props: {
    columns: {
      type: Array,
      required: true,
    },
    tools: {
      type: Object,
      default: {
        query: true,
        import: false,
        export: false,
        saveApi: false,
      },
    },

    reqConfig: {
      type: Object,
      default: () => {
        return {};
      },
    },
    saveData: {
      type: Function,
      required: true,
    },
    handleExport: {
      type: Function,
    },
    delData: {
      type: Function,
    },
  },
  data() {
    return {
      tableData: [],
      // 0 添加 1 编辑
      operate: 0,
      flag: true,
      savaData: [],
      exportData: [],
      EditDisabled: false,
      checkList: [],
      dialogVisible: false,
    };
  },
  async created() {
    // this.getData(); //一打开页面获取list
    // if(this.flag){
    //  await this.$nextTick()
    this.handleAdd(); // 新增空白行
    //   this.flag = false
    // }
  },
  watch: {
    tableData: {
      handler() {
        // 数组的最后一条有数据，就新增一个空白行
        const lastData = this.tableData[this.tableData.length - 1];
        if (!this.isEmptyRow(lastData)) {
          // table新增一行空白行
          this.handleAdd(+new Date());
        }
      },
      deep: true,
    },
  },
  methods: {
    change(e) {
      console.log(1, e);
    },
    async getData() {
      const res = await request(this.reqConfig);
      console.log("后台数据111-", res);
      this.tableData = res.rows || res.data;
      this.$message.success("成功获取最新数据");
      !this.savaData.length || (this.savaData = []); //点击查询的时候把上一次的编辑和新增的数组清空
    },
    handleAdd(newDate) {
      // this.operate = 0;
      const newRow = {};
      this.columns.forEach((column) => {
        newRow[column.prop] = null;
        newRow.tempId = newDate;
      });
      newRow.editable = true;
      this.tableData.push(newRow);
    },
    async handleSave() {
      if (!this.savaData.length) {
        return this.$message.error("没有对数据进行修改");
      }
      const dataToSave = this.tableData.filter((row) => !this.isEmptyRow(row));
      dataToSave.forEach((row) => {
        row.editable = false;
      });
      console.log("点击过的数组", this.savaData);
      try {
        // 再把空数据过滤
        const list = this.savaData.filter((el) => {
          delete el.editable;
          delete el.tempId;
          return !this.isEmptyRow(el);
        });
        if (list.length) {
          await this.saveData(list);
          await this.getData();
        } else {
          return this.$message.error("没有对数据进行修改");
        }
        this.savaData = []; //清空批量编辑&新增
      } catch {
        this.$message.error("保存失败");
        // await this.getData();
        // 把saveData 在 tableData 删除——————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
      } finally {
      }
    },
    editRow(row, col) {
      if (col?.label === "操作") return;
      // console.log(!this.isEmptyRow(row));
      if (!this.isEmptyRow(row) && this.savaData.length) {
        const found = this.savaData.find((el) => {
          return el.id ? el.id === row.id : el.tempId === row.tempId;
        });
        //把已经存在的数据删除加入最新的数据
        if (found) {
          this.savaData = this.savaData.filter((el) => {
            return el.id ? el.id !== found.id : el.tempId !== found.tempId;
          });
        }
      }
      // 没有重复就直接添加到数组
      this.savaData.push(row);
      if (!row.editable) {
        this.tableData = this.tableData.map((item) => {
          if (item === row) {
            return { ...item, editable: true };
          }
          return { ...item, editable: false };
        });
      }
    },
    saveRow(row) {
      row.editable = false;
    },
    isEmptyRow(row) {
      return this.columns.every((column) => !row[column.prop]);
    },
    async doDel(id) {
      try {
        await this.$confirm("确定要删除吗？", "提示", {
          confirmButtonText: "确定",
          cancelButtonText: "取消",
          type: "warning",
        });
        console.log("删除操作的id", id);
        if (id) {
          await this.delData(id);
          await this.getData();
        }
        this.$message.success("删除成功");
      } catch {
        console.log("出错了");
      }
    },
    // 编辑
    handleEdit(row) {
      // 0 添加 1 编辑
      this.operate = 1;
      if (!row.editable) {
        this.tableData = this.tableData.map((item) => {
          if (item === row) {
            return { ...item, editable: true };
          }
          return { ...item, editable: false };
        });
      }
    },
    // 点击保存
    // async saveEdit(item) {
    //   // 对象为空不往下执行
    //   if (this.isEmptyRow(item)) return this.$message.error("请先输入内容");
    //   this.tableData.forEach((row) => {
    //     row.editable = false;
    //   });
    //   // 判断id是否已经存在，不存在就是新增操作，否则是编辑
    //   const idName = this.columns[this.columns.length - 1].id;
    //   if (item[idName]) this.operate = 1;

    //   console.log("operate", this.operate);
    //   console.log(
    //     "编辑？？？",
    //     this.operate,
    //     item,
    //     "--",
    //     item[idName],
    //     "--",
    //     idName
    //   );
    //   try {
    //     await this.saveData(item, this.operate);
    //     await this.getData();
    //     this.$message.success(this.operate ? "编辑成功" : " 新增成功");
    //   } catch {}
    // },

    // 针对需要下拉框的字段，id转文字
    id2Text(opt, aa) {
      if (!aa) return;
      const val = JSON.parse(aa);
      if (typeof val === "object" && val) {
        const list_text = val.map((v) => {
          const obj = opt && opt.find((el) => el.value === v); // 找到匹配的id对象
          return obj ? obj.label : "";
        });
        return list_text.join(",");
      } else {
        return opt.find((v) => v.value === val)?.label;
      }
    },
    confirmDialog(opt, row, prop) {
      // 把文字转id数组
      let idList;
      if (this.checkList.length) {
        idList = this.checkList.map((v) => {
          const obj = opt && opt.find((el) => el.label === v); // 找到匹配的id对象
          return obj ? obj.value : "";
        });
      }
      row[prop] = JSON.stringify(idList);
      this.dialogVisible = false;
    },
    multiChexk(opt, aa) {
      let list_text = [];
      if (aa) {
        const val = JSON.parse(aa);
        list_text = val.map((v) => {
          const obj = opt && opt.find((el) => el.value === v); // 找到匹配的id对象
          return obj ? obj.label : "";
        });
      }
      this.checkList = list_text;
      this.dialogVisible = true;
    },
    handleImport() {},
    clickOpt(e, row, col) {
      if (!e) {
        this.validate(row, col);
      }
      if (!this.isEmptyRow(row) && this.savaData.length) {
        const found = this.savaData.find((el) => {
          return el.id ? el.id === row.id : el.tempId === row.tempId;
        });
        //把已经存在的数据删除加入最新的数据
        if (found) {
          this.savaData = this.savaData.filter((el) => {
            return el.id ? el.id !== found.id : el.tempId !== found.tempId;
          });
        }
      }
      // 没有重复就直接添加到数组
      this.savaData.push(row);
    },
    validate(item, column) {
      try {
        if (column?.relues && column.relues.required && !item[column.prop]) {
          return this.$message.error(`${column?.label}不能为空`);
          //  return await  this.$confirm(`${column.label}不能为空`, "提示", {
          //   confirmButtonText: "确定",
          //   type: "warning",
          // });
        }
        if (column?.relues && item[column.prop] && column?.relues.validate) {
          if (!column.relues.validate(item[column.prop])) {
            // 校验失败，把数据清空
            item[column.prop] = "";
          }
        }
      } catch {}
    },
  },
};
</script>
<style lang="scss" scoped>
::v-deep .el-checkbox__input.is-disabled.is-checked .el-checkbox__inner::after {
  border-color: blue;
}
</style>


